/**
 * Filename: UpLoadService.java
 *
 * @author Firefly
 * @contact postfirefly@163.com
 * @time 2016/3/17 16:06
 */
package com.github.postsanf.yinian.service;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.github.postsanf.yinian.BaseIntentService;
import com.github.postsanf.yinian.R;
import com.github.postsanf.yinian.bean.YNImport;
import com.github.postsanf.yinian.bean.YNResponse;
import com.github.postsanf.yinian.constants.ACTIONs;
import com.github.postsanf.yinian.constants.CommonConstants;
import com.github.postsanf.yinian.constants.SelectedImg;
import com.github.postsanf.yinian.entity.YNUpTokenResponse;
import com.github.postsanf.yinian.utils.ReqUtils;
import com.github.postsanf.yinian.utils.SpUtils;
import com.litesuits.http.exception.HttpException;
import com.litesuits.http.listener.HttpListener;
import com.litesuits.http.request.StringRequest;
import com.litesuits.http.request.param.HttpMethods;
import com.litesuits.http.response.Response;
import com.qiniu.android.http.ResponseInfo;
import com.qiniu.android.storage.UpCancellationSignal;
import com.qiniu.android.storage.UpCompletionHandler;
import com.qiniu.android.storage.UpProgressHandler;
import com.qiniu.android.storage.UploadManager;
import com.qiniu.android.storage.UploadOptions;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

/**
 * 一键上传后台异步单线程断点续传
 */
public class ImportService extends BaseIntentService {
    private UploadManager mUpManager;
    private boolean isFirst = true;     // 首次获取Token
    private Timer timer;
    private String fileKey;
    private int total = 0;
    Map<String, List<String>> keyUrl = new HashMap<>();
    Map<String, Long> sizeUrl = new HashMap<>();
    Map<String, List<String>> camap = new HashMap<>();
    private int picNumber;

    public ImportService() {
        super("ImportService");
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    break;
                case 1:
                    String path = (String) msg.obj;
                    String time = getTime(path);
                    Long size = getSize(path);
                    if (keyUrl.containsKey(time)) {
                        List<String> urlList = keyUrl.get(time);
                        urlList.add(fileKey);
                        keyUrl.put(time, urlList);
                    } else {
                        List<String> strings = new ArrayList<>();
                        strings.add(fileKey);
                        keyUrl.put(time, strings);
                    }
                    if (sizeUrl.containsKey(time)) {
                        Long aLong = sizeUrl.get(time);
                        aLong += size;
                        sizeUrl.put(time, aLong);
                    } else {
                        sizeUrl.put(time, size);
                    }
                    ++total;
                    int progress = (int) ((total * 1.0 / picNumber) * 100);
                    Intent intent = new Intent(ACTIONs.actionUpdateProgress);
                    intent.putExtra(ACTIONs.aUpProgress, progress);
                    sendBroadcast(intent);
                    if (progress < 100) {
                        SharedPreferences sp = getSharedPreferences("nullUpkey", Context.MODE_PRIVATE);
                        SharedPreferences.Editor edit = sp.edit();
                        edit.putInt("progress", progress);
                        edit.commit();
                    } else {
                        SharedPreferences sp = getSharedPreferences("nullUpkey", Context.MODE_PRIVATE);
                        SharedPreferences.Editor edit = sp.edit();
                        edit.putInt("progress", 0);
                        edit.commit();
                    }
                    Log.d("yuhao", "progress=" + progress);
                    break;
//                case 2:
//                    JSONObject jsonObject = null;
//                    JSONArray jsonArray = new JSONArray();
//                    Iterator<Map.Entry<String, List<String>>> it = keyUrl.entrySet().iterator();
//                    while (it.hasNext()) {
//                        Map.Entry<String, List<String>> entry = it.next();
//                        jsonObject = new JSONObject();
//                        String key = entry.getKey();
//                        Long aLong = sizeUrl.get(key);
//                        long totalSize = aLong / 1024;
//                        try {
//                            jsonObject.put("date", key);
//                            List<String> value = entry.getValue();
//                            String url = null;
//                            for (int i = 0; i < value.size(); i++) {
//                                String strings = value.get(i);
//                                if (url == null) {
//                                    url = strings;
//                                } else {
//                                    url = url + "," + strings;
//                                }
//                            }
//                            jsonObject.put("photo", url);
//                            jsonObject.put("storage", totalSize);
//                            jsonArray = jsonArray.put(jsonObject);
//                        } catch (JSONException e) {
//                            e.printStackTrace();
//                        }
//                    }
//                    Log.d("yuhao", "jsonArray1=" + jsonArray.toString());
//                    UploadToYiNian(jsonArray);
//                    break;
                case 3:
                    YNImport ynImport = (YNImport) msg.obj;
                    Map<String, List<String>> uploadkey = ynImport.getKeyUrl();
                    Map<String, Long> uploadsize = ynImport.getSizeUrl();
                    JSONArray jsonArray = new JSONArray();
                    Iterator<Map.Entry<String, List<String>>> it = uploadkey.entrySet().iterator();
                    while (it.hasNext()) {
                        Map.Entry<String, List<String>> entry = it.next();
                        JSONObject jsonObject = new JSONObject();
                        String key = entry.getKey();
                        Long aLong = uploadsize.get(key);
                        long totalSize = aLong / 1024;
                        try {
                            jsonObject.put("date", key);
                            List<String> value = entry.getValue();
                            String url = null;
                            for (int i = 0; i < value.size(); i++) {
                                String strings = value.get(i);
                                if (url == null) {
                                    url = strings;
                                } else {
                                    url = url + "," + strings;
                                }
                            }
                            jsonObject.put("photo", url);
                            jsonObject.put("storage", totalSize);
                            jsonArray = jsonArray.put(jsonObject);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                    Log.d("yuhao", "jsonArray1=" + jsonArray.toString());
                    UploadToYiNian(jsonArray, ynImport.isOver());
                    break;
            }
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        mUpManager = application.getUploadManager();
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            final String action = intent.getAction();
            switch (action) {
                case ACTIONs.actionPublishPhoto:
                    //由于莫名其妙离开WIFI时还会收到广播启动服务所以加上这个判断
                    ConnectivityManager connectivityManager = (ConnectivityManager)
                            getSystemService(Context.CONNECTIVITY_SERVICE);
                    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
                    if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                        //上传照片的总数
                        picNumber = intent.getIntExtra(ACTIONs.picNumber, 0);
                        SharedPreferences sp = getSharedPreferences("nullUpkey", Context.MODE_PRIVATE);
                        boolean exit = sp.getBoolean("exit", false);
                        //未获取key的照片数
                        int surplus = sp.getInt("picNumber", 0);
                        //判断是否为断点续传
                        if (exit && surplus != 0) {
                            total = picNumber - surplus;
                            Log.d("yuhao", "total=" + total);
                            SharedPreferences.Editor edit = sp.edit();
                            edit.putBoolean("exit", false);
                            edit.commit();
                        }
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                getToken();
                            }
                        }).start();
                    }
                    break;
            }
        }
    }


    private void getToken() {
        if (isFirst) {
//            Log.d("yuhao", "getPrivateSpaceUploadToken");
            doTokenPrepare();
            //如果token无效2秒后自动上传
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            getToken();
            return;
        }
        SharedPreferences sp = getSharedPreferences("nullUpkey", Context.MODE_PRIVATE);
        String nullUpkey = sp.getString("nullUpkey", null);
        Log.d("yuhao", "nullUpkey=" + nullUpkey);
        toHashMap(nullUpkey);
        Iterator<Map.Entry<String, List<String>>> it = camap.entrySet().iterator();
        List<String> list = new ArrayList<>();
        while (it.hasNext()) {
            Map.Entry<String, List<String>> entry = it.next();
            List<String> value = entry.getValue();
            for (int i = 0; i < value.size(); i++) {
                list.add(value.get(i));
            }
        }
        if (list.size() > 0) {
            uploadToqiniu(list);
        }
        camap.clear();
    }

    private String uploadToqiniu(final List<String> list) {
        final String path = list.get(0);
        final File uploadFile = new File(path);
        UploadOptions uploadOptions = new UploadOptions(null, null, false,
                new UpProgressHandler() {
                    @Override
                    public void progress(String key, double percent) {
                    }
                }, new UpCancellationSignal() {
            @Override
            public boolean isCancelled() {
                return false;
            }
        });
        String prefix = path.substring(path.lastIndexOf(".") + 1);
        // 为图片重命名
        String imgName = UUID.randomUUID().toString() + "." + prefix;
        mUpManager.put(uploadFile, imgName, application.getUpToken(),
                new UpCompletionHandler() {
                    @Override
                    public void complete(String key, ResponseInfo respInfo, JSONObject jsonData) {
                        if (respInfo.isOK()) {
                            try {
                                fileKey = jsonData.getString("key");
                                List<String> strings = SelectedImg.dateUrl.get(getTime(path));
                                if (strings != null) {
                                    strings.remove(path);
                                }
                                SelectedImg.dateUrl.put(getTime(path), strings);
                                Message message = new Message();
                                message.what = 1;
                                message.obj = path;
                                handler.sendMessage(message);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        } else {
                            showLog("----------------------------七牛云上传图片失败---------------------------------");
                            fileKey = null;
                        }
                        list.remove(path);
                        //将未上传获取key的图片存入本地
                        saveNoKeyPic(list.size());
                        if (list.size() == 0) {
                            //由于莫名其妙的图片上传完毕而100%进度没有存入本地所以延时发送消息2
//                            handler.postDelayed(new Runnable() {
//                                @Override
//                                public void run() {
//                                    handler.sendEmptyMessage(2);
//                                }
//                            }, 20);
                            if (keyUrl.size() <= 100) {
                                new Handler().postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        YNImport ynImport = new YNImport();
                                        Iterator<Map.Entry<String, List<String>>> it = keyUrl.entrySet().iterator();
                                        while (it.hasNext()) {
                                            Map.Entry<String, List<String>> entry = it.next();
                                            ynImport.getKeyUrl().put(entry.getKey(),entry.getValue());
                                        }
                                        Iterator<Map.Entry<String, Long>> it2 = sizeUrl.entrySet().iterator();
                                        while (it2.hasNext()) {
                                            Map.Entry<String,  Long> entry2 = it2.next();
                                            ynImport.getSizeUrl().put(entry2.getKey(),entry2.getValue());
                                        }
                                        ynImport.setOver(true);
                                        Message message = new Message();
                                        message.what = 3;
                                        message.obj = ynImport;
                                        handler.sendMessage(message);
                                        keyUrl.clear();
                                        sizeUrl.clear();
                                    }
                                }, 20);
                            }
                        } else {
                            if (list.size() % 100 == 0) {
                                new Handler().postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        YNImport ynImport = new YNImport();
                                        Iterator<Map.Entry<String, List<String>>> it = keyUrl.entrySet().iterator();
                                        while (it.hasNext()) {
                                            Map.Entry<String, List<String>> entry = it.next();
                                            ynImport.getKeyUrl().put(entry.getKey(),entry.getValue());
                                        }
                                        Iterator<Map.Entry<String, Long>> it2 = sizeUrl.entrySet().iterator();
                                        while (it2.hasNext()) {
                                            Map.Entry<String,  Long> entry2 = it2.next();
                                            ynImport.getSizeUrl().put(entry2.getKey(),entry2.getValue());
                                        }
                                        ynImport.setOver(false);
                                        Message message = new Message();
                                        message.what = 3;
                                        message.obj = ynImport;
                                        handler.sendMessage(message);
                                        keyUrl.clear();
                                        sizeUrl.clear();
                                    }
                                }, 20);
                            }
                            if (SpUtils.getBoolean(ImportService.this, "wifi")) {
                                uploadToqiniu(list);
                            } else {
                                showToast("请在WIFI环境下上传图片");
                            }
                        }
                    }
                }, uploadOptions);
        return fileKey;
    }

    private void saveNoKeyPic(int surplus) {
        String s = toJson();
        SharedPreferences sp = getSharedPreferences("nullUpkey", Context.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        edit.putString("nullUpkey", s);
        //剩余未获取可以的图片存入本地
        edit.putInt("picNumber", surplus);
        if (surplus == 0) {
            edit.putInt("totalPic", 0);
        }
        edit.commit();
    }

    private String getTime(String path) {
        File file = new File(path);
        long imgTime = file.lastModified();
        Date currentTime = new Date(imgTime);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    private Long getSize(String path) {
        File file = new File(path);
        long length = file.length();
        return length;
    }


    // 上传并删除
    private void UploadToYiNian(JSONArray jsonArray, final boolean isOver) {
        String urlsto = getString(R.string.BASE_URL) + getString(R.string.backupPhotos);
        LinkedHashMap<String, String> mParam = new LinkedHashMap<>();
        mParam.put(CommonConstants.YNS_USER_ID, application.getCurID() + "");
        mParam.put(CommonConstants.DATA, jsonArray.toString());
        mParam.put(CommonConstants.DEVICE, "android");
        StringRequest req = new StringRequest(urlsto)
                .setMethod(HttpMethods.Post)
                .setParamMap(mParam)
                .setHttpListener(new HttpListener<String>(true, false, true) {
                    @Override
                    public void onSuccess(String s, Response<String> response) {
                        YNResponse res = gson.fromJson(s, YNResponse.class);
                        if (TextUtils.equals(res.getMsg(), "success")) {
                            Log.d("yuhao", "UploadToYiNian=" + "isSuccess");
                            // 通知动态更新
                            if (isOver)
                                sendBroadcast(new Intent(ACTIONs.actionDeleteList));
                        } else {
                            Log.d("yuhao", "UploadToYiNian=" + "fail");
                        }
                    }

                    @Override
                    public void onFailure(HttpException e, Response<String> response) {
                        showToast(CommonConstants.YN_NET_LINK);

                    }
                });
        liteHttp.executeAsync(req);
    }

    // 主动获取Token  间隔30分钟
    private void doTokenPrepare() {
        if (timer == null) {
            timer = new Timer();
        }
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                // getToken();
                getPrivateSpaceUploadToken();
            }
        }, 300, 30 * 60 * 1000);
    }

    private void getPrivateSpaceUploadToken() {
        StringRequest req = new StringRequest(getString(R.string.BASE_URL) + getString(R.string.ynGetPrivateSpaceUploadToken))
                .setMethod(HttpMethods.Post)
                .setHttpListener(new HttpListener<String>(true, false, true) {
                    @Override
                    public void onSuccess(String s, Response<String> response) {
                        YNUpTokenResponse resToken = gson.fromJson(s, YNUpTokenResponse.class);
                        if (ReqUtils.isSuccess(resToken.getCode())) {
                            application.setUpToken(resToken.getData().get(0).getToken());
                            if (isFirst) {
                                isFirst = false;
                            }
                            handler.sendEmptyMessage(0);
                        } else {
                            showToast(resToken.getMsg());
                        }
                    }

                    @Override
                    public void onFailure(HttpException e, Response<String> response) {
                        //  showToast(CommonConstants.YN_NET_LINK);
                    }
                });
        liteHttp.executeAsync(req);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

    }

    private void toHashMap(String str) {
        //将json转成hashMap
        JSONArray jsonArray1 = null;
        try {
            jsonArray1 = new JSONArray(str);
            for (int i = 0; i < jsonArray1.length(); i++) {
                JSONObject obj = jsonArray1.optJSONObject(i);
                String date = obj.getString("date");
                String photo = obj.getString("photo");
                String[] split = photo.split(",");
                List<String> pic = new ArrayList<>();
                for (int j = 0; j < split.length; j++) {
                    pic.add(split[j]);
                }
                camap.put(date, pic);
                SelectedImg.dateUrl.put(date, pic);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private String toJson() {
        JSONObject jsonObject1 = new JSONObject();
        JSONArray jsonArray1 = new JSONArray();
        //将图片数据转换成json字符串
        Iterator<Map.Entry<String, List<String>>> it = SelectedImg.dateUrl.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, List<String>> entry = it.next();
            String key = entry.getKey();
            try {
                jsonObject1.put("date", key);
                List<String> value = entry.getValue();
                String url = null;
                if (value != null) {
                    for (int i = 0; i < value.size(); i++) {
                        String strings = value.get(i);
                        if (url == null) {
                            url = strings;
                        } else {
                            url = url + "," + strings;
                        }
                    }
                }
                jsonObject1.put("photo", url);
                jsonArray1 = jsonArray1.put(jsonObject1);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return jsonArray1.toString();
    }
}